home *** CD-ROM | disk | FTP | other *** search
/ Sprite 1984 - 1993 / Sprite 1984 - 1993.iso / src / cmds / lfscheck / RCS / lfscheck.c,v < prev   
Encoding:
Text File  |  1992-03-12  |  40.1 KB  |  1,329 lines

  1. head     1.1;
  2. branch   ;
  3. access   ;
  4. symbols  ;
  5. locks    mendel:1.1; strict;
  6. comment  @ * @;
  7.  
  8.  
  9. 1.1
  10. date     90.06.01.10.10.18;  author mendel;  state Exp;
  11. branches ;
  12. next     ;
  13.  
  14.  
  15. desc
  16. @Old summary format.
  17. @
  18.  
  19.  
  20.  
  21. 1.1
  22. log
  23. @Initial revision
  24. @
  25. text
  26. @/* 
  27.  * checkLfs.c --
  28.  *
  29.  *    The checkLfs program - Check an LFS file system to make sure it
  30.  *    is consistent.
  31.  *
  32.  * Copyright 1989 Regents of the University of California
  33.  * Permission to use, copy, modify, and distribute this
  34.  * software and its documentation for any purpose and without
  35.  * fee is hereby granted, provided that the above copyright
  36.  * notice appear in all copies.  The University of California
  37.  * makes no representations about the suitability of this
  38.  * software for any purpose.  It is provided "as is" without
  39.  * express or implied warranty.
  40.  */
  41.  
  42. #ifndef lint
  43. static char rcsid[] = "$Header: /sprite/lib/forms/RCS/proto.c,v 1.2 89/01/07 04:12:18 rab Exp $ SPRITE (Berkeley)";
  44. #endif /* not lint */
  45.  
  46. #include <sprite.h>
  47. #include <stdio.h>
  48. #include <option.h>
  49. #include <stdlib.h>
  50. #include <string.h>
  51. #include <sys/file.h>
  52. #include <alloca.h>
  53.  
  54. #include "user/fs.h"
  55. #include "kernel/fs.h"
  56. #include "kernel/dev.h"
  57. #include "kernel/fsdm.h"
  58. #include "kernel/devDiskLabel.h"
  59.  
  60. #include "lfsDesc.h"
  61. #include "lfsDescMap.h"
  62. #include "lfsFileLayout.h"
  63. #include "lfsSegLayout.h"
  64. #include "lfsStableMem.h"
  65. #include "lfsSuperBlock.h"
  66. #include "lfsUsageArray.h"
  67.  
  68.  
  69. #define    BlockToSegmentNum(block)    (((block) - superBlockPtr->hdr.logStartOffset)/(superBlockPtr->usageArray.segmentSize/blockSize))
  70. /*
  71.  * The descriptor map and segment usage array of file system.
  72.  */
  73. LfsDescMapEntry *descMapPtr = (LfsDescMapEntry *) NIL;
  74. LfsDescMapCheckPoint *descMapCheckPointPtr;
  75. LfsStableMemCheckPoint *descMapStableMemPtr;
  76. int              *descMapBlockIndexPtr;
  77. Boolean             *descFoundArray;
  78.  
  79. LfsSegUsageEntry *usageArrayPtr = (LfsSegUsageEntry *) NIL;
  80. LfsSegUsageCheckPoint *usageArrayCheckPointPtr;
  81. LfsStableMemCheckPoint *usageArrayStableMemPtr;
  82. int              *usageArrayBlockIndexPtr;
  83.  
  84. /*
  85.  * The super block of the file system.
  86.  */
  87. LfsSuperBlock    *superBlockPtr;
  88.  
  89.  
  90. typedef struct BlockInfo {
  91.     int    type;        /* Type of block. See defines below. */
  92.     int fileNum;    /* File number of block's owner. */
  93.     int blockNum;    /* Block number of block's owner. */
  94.     Boolean  found;    /* TRUE if found in summary region. */
  95. } BlockInfo;
  96. #define    UNUSED    0
  97. #define    FILE    1
  98. #define    DESC_MAP 2
  99. #define USAGE_ARRAY 3
  100. #define    SUMMARY        4
  101. #define CHECKPOINT  5
  102. #define    DESC       6
  103.  
  104. BlockInfo    *blockInfoArray;
  105. int        numBlocks;
  106. int        *activeBytesArray;
  107.  
  108. int    blockSize = 512;
  109. int    offset = 64*512;
  110. Boolean dumpFlag = FALSE;
  111. char    *deviceName;
  112.  
  113. Option optionArray[] = {
  114.     {OPT_DOC, (char *) NULL,  (char *) NULL,
  115.     "This program the file or a LFS file system.\n Synopsis: \"checkLfs [switches] deviceName\"\n Command-line switches are:"},
  116.     {OPT_INT, "blockSize", (Address) &blockSize, 
  117.     "Block size of file system."},
  118.     {OPT_INT, "offset", (Address) &offset, 
  119.     "Offset into device to start file system."},
  120.     {OPT_TRUE, "dump", (Address) &dumpFlag, 
  121.     "Print out a description of file system."},
  122. };
  123. /*
  124.  * Forward routine declartions. 
  125.  */
  126. static void PrintSegUsage();
  127. static int DiskRead();
  128. static Boolean IsZero();
  129.  
  130.  
  131. /*
  132.  *----------------------------------------------------------------------
  133.  *
  134.  * main --
  135.  *
  136.  *    Main routine of checkLfs - parse arguments and do the work.
  137.  *
  138.  * Results:
  139.  *    None.
  140.  *
  141.  * Side effects:
  142.  *    None.
  143.  *
  144.  *----------------------------------------------------------------------
  145.  */
  146.  
  147. int
  148. main(argc,argv)
  149.     int    argc;
  150.     char *argv[];
  151. {
  152.     int       diskFd, maxCheckPointSize, maxCheckPointBlocks, moduleType;
  153.     int        blocks, blocksPerSeg, segNum;
  154.     LfsCheckPointHdr    checkPointHdr[2], *checkPointHdrPtr;
  155.     char        *segmentPtr, *checkPointPtr, *trailerPtr;
  156.     LfsSegSummaryHdr    *sumHdrPtr;
  157.     LfsCheckPointRegion *regionPtr;
  158.     LfsSegSummary     *segSumPtr;
  159.     LfsCheckPointHdr    *cpHdrPtr, *oldCheckPointPtr;
  160.     LfsCheckPointTrailer *trailPtr;
  161.     int            choosenOne, i;
  162.  
  163.  
  164.  
  165.     argc = Opt_Parse(argc, argv, optionArray, Opt_Number(optionArray), 0);
  166.     if (argc != 2) { 
  167.          Opt_PrintUsage(argv[0], optionArray, Opt_Number(optionArray));
  168.      exit(1);
  169.     } else {
  170.     deviceName = argv[1];
  171.     }
  172.     diskFd = open(deviceName, O_RDONLY, 0);
  173.     if (diskFd < 0) {
  174.     fprintf(stderr,"%s: ", argv[0]);
  175.     perror(deviceName);
  176.     exit(1);
  177.     }
  178.     /*
  179.      * Fill in the super block header.
  180.      */
  181.     offset = offset/blockSize;
  182.     superBlockPtr = (LfsSuperBlock *) malloc(LFS_SUPER_BLOCK_SIZE);
  183.     if (DiskRead(diskFd, offset, sizeof(LfsSuperBlock), (char *)superBlockPtr)
  184.         != sizeof(LfsSuperBlock)) {
  185.     fprintf(stderr,"%s: Can't read superblock.\n", argv[0]);
  186.     exit(1);
  187.  
  188.     }
  189.     if (superBlockPtr->hdr.magic != LFS_SUPER_BLOCK_MAGIC) {
  190.     fprintf(stderr,"%s: Bad magic number for filesystem\n", argv[0]);
  191.     exit(1);
  192.     }
  193.     if (dumpFlag) {
  194.        PrintSuperBlock(superBlockPtr);
  195.     }
  196.     if (!IsZero(superBlockPtr->hdr.padding, sizeof(superBlockPtr->hdr.padding))
  197.         ) {
  198.     fprintf(stderr,"%s: SuperBlockHdr padding is not zero.\n",argv[0]);
  199.     }
  200.  
  201.     /*
  202.      * Examine the two checkpoint areas to locate the checkpoint area with the
  203.      * newest timestamp.
  204.      */
  205.     if (DiskRead(diskFd, superBlockPtr->hdr.checkPointOffset[0],
  206.         sizeof(LfsCheckPointHdr), (char *) (checkPointHdr+0)) != 
  207.     sizeof(LfsCheckPointHdr)) {
  208.     fprintf(stderr,"%s: Can't read checkPointHeader 0.\n", argv[0]);
  209.     exit(1);
  210.     }
  211.     if (dumpFlag) {
  212.     PrintCheckPointHdr(checkPointHdr, 0);
  213.     }
  214.     if (DiskRead(diskFd, superBlockPtr->hdr.checkPointOffset[1],
  215.         sizeof(LfsCheckPointHdr), (char *) (checkPointHdr+1))  != 
  216.     sizeof(LfsCheckPointHdr)) {
  217.     fprintf(stderr,"%s: Can't read checkPointHeader 1.\n", argv[0]);
  218.     exit(1);
  219.     }
  220.     if (dumpFlag) {
  221.     PrintCheckPointHdr(checkPointHdr+1, 1);
  222.     }
  223.  
  224.     choosenOne = (checkPointHdr[0].timestamp<checkPointHdr[1].timestamp) ?
  225.                 1 : 0;
  226.  
  227.     maxCheckPointSize = superBlockPtr->hdr.maxCheckPointBlocks * 
  228.                 blockSize;
  229.     checkPointPtr = malloc(maxCheckPointSize);
  230.     if (DiskRead(diskFd, superBlockPtr->hdr.checkPointOffset[choosenOne],
  231.         maxCheckPointSize, checkPointPtr) != maxCheckPointSize) {
  232.     fprintf(stderr,"%s: Can't read checkPoint %d\n", argv[0], choosenOne);
  233.     }
  234.  
  235.  
  236.     checkPointHdrPtr = (LfsCheckPointHdr *) checkPointPtr;
  237.     trailerPtr = (checkPointPtr + checkPointHdrPtr->size - 
  238.                 sizeof(LfsCheckPointTrailer));
  239.     trailPtr = (LfsCheckPointTrailer *) trailerPtr;
  240.     if (trailPtr->timestamp != checkPointHdrPtr->timestamp) {
  241.     fprintf(stderr,"%s: Header timestamp %d doesn't match trailer timestamp %d\n", argv[0], checkPointHdrPtr->timestamp, trailPtr->timestamp);
  242.     }
  243.     printf("Using checkpoint area %d with timestamp %d domain %d (%s)\n",
  244.     choosenOne, checkPointHdrPtr->timestamp, 
  245.     checkPointHdrPtr->domainNumber,checkPointHdrPtr->domainPrefix);
  246.  
  247.     checkPointPtr = checkPointPtr + sizeof(LfsCheckPointHdr);
  248.  
  249.     numBlocks = superBlockPtr->usageArray.numberSegments * 
  250.             (superBlockPtr->usageArray.segmentSize/blockSize) +
  251.             superBlockPtr->hdr.logStartOffset;
  252.     blockInfoArray = (BlockInfo *) malloc(numBlocks * sizeof(BlockInfo));
  253.     bzero((char *) blockInfoArray, numBlocks * sizeof(BlockInfo));
  254.     descFoundArray = (Boolean *) malloc(sizeof(Boolean) * 
  255.                 superBlockPtr->descMap.maxDesc);
  256.     bzero(descFoundArray, sizeof(Boolean)* superBlockPtr->descMap.maxDesc);
  257.  
  258.     for (i = 0; i < superBlockPtr->hdr.logStartOffset; i++) {
  259.     blockInfoArray[i].type = CHECKPOINT;
  260.     blockInfoArray[i].found = TRUE;
  261.     }
  262.     activeBytesArray = (int *) malloc(sizeof(activeBytesArray[0]) * 
  263.                 superBlockPtr->usageArray.numberSegments);
  264.     bzero((char *) activeBytesArray, sizeof(activeBytesArray[0]) * 
  265.                 superBlockPtr->usageArray.numberSegments);
  266.     while (checkPointPtr < trailerPtr) { 
  267.     regionPtr = (LfsCheckPointRegion *) checkPointPtr;
  268.     if (regionPtr->size == 0) {
  269.         break;
  270.     }
  271.     switch (regionPtr->type) {
  272.     case LFS_SEG_USAGE_MOD:
  273.         LoadUsageArray(diskFd, regionPtr->size - sizeof(*regionPtr),
  274.                 (char *) (regionPtr+1));
  275.         break;
  276.     case LFS_DESC_MAP_MOD:
  277.         LoadDescMap(diskFd, regionPtr->size - sizeof(*regionPtr),
  278.                 (char *) (regionPtr+1));
  279.         break;
  280.     case LFS_FILE_LAYOUT_MOD:
  281.         if (regionPtr->size != sizeof(*regionPtr)) {
  282.         fprintf(stderr,"%s: Bad size %d for FILE_LAYOUT checkpoint\n",
  283.                 argv[0],regionPtr->size);
  284.         }
  285.         break;
  286.     default: {
  287.         fprintf(stderr,"%s: Unknown region type %d of size %d\n", argv[0],
  288.             regionPtr->type, regionPtr->size);
  289.         break;
  290.         }
  291.     }
  292.     checkPointPtr += regionPtr->size;
  293.     }
  294.  
  295.     CheckAllFiles(diskFd);
  296.     CheckUsageArray(diskFd);
  297.     CheckSummaryRegions(diskFd);
  298.     for (i = 0; i < numBlocks; i++) {
  299.     if ((blockInfoArray[i].type != UNUSED) && !blockInfoArray[i].found) {
  300.         fprintf(stderr,"No summary region for block at %d own by <%d,%d,%d>\n",
  301.             i * blockSize,
  302.             blockInfoArray[i].type,
  303.             blockInfoArray[i].fileNum,
  304.             blockInfoArray[i].blockNum);
  305.     }
  306.  
  307.     }
  308.     for (i = 2; i < superBlockPtr->descMap.maxDesc; i++) {
  309.     if ((descMapPtr[i].flags == LFS_DESC_MAP_ALLOCED) &&
  310.         !descFoundArray[i]) {
  311.         fprintf(stderr,"No summary region for desc %d; should be a %d\n",
  312.             i, descMapPtr[i].blockAddress);
  313.     }
  314.     }
  315.     exit(0);
  316. }
  317. char *GetState();
  318.  
  319. /*
  320.  *----------------------------------------------------------------------
  321.  *
  322.  * LoadUsageArray --
  323.  *
  324.  *    Load the segment usage array into memory.
  325.  *
  326.  * Results:
  327.  *    TRUE if array can be loaded. FALSE otherwise.
  328.  *
  329.  * Side effects:
  330.  *    None.
  331.  *
  332.  *----------------------------------------------------------------------
  333.  */
  334.  
  335. Boolean
  336. LoadUsageArray(diskFd, checkPointSize, checkPointPtr)
  337.     int    diskFd;
  338.     int    checkPointSize;
  339.     char *checkPointPtr;
  340. {
  341.     LfsSegUsageParams    *usagePtr;
  342.     LfsSegUsageCheckPoint    *cp;
  343.     LfsSegUsageEntry        *array;
  344.     int                i, blockNum;
  345.     char            *dataPtr;
  346.     LfsStableMemCheckPoint *cpPtr;
  347.     int            arraySize;
  348.     LfsStableMemParams  *smemParamsPtr;
  349.     int            *blockIndexPtr;
  350.     int    numClean,  numDirty, numFull;
  351.     int freeBlocks;
  352.     Boolean ret = TRUE;
  353.  
  354.     usagePtr = &(superBlockPtr->usageArray);
  355.     smemParamsPtr = &(superBlockPtr->usageArray.stableMem);
  356.  
  357.  
  358.     usageArrayCheckPointPtr = cp = (LfsSegUsageCheckPoint *) checkPointPtr;
  359.     if (dumpFlag) { 
  360.     printf("NumClean segments %d (%3.1f%%) NumDirty %d (%3.1f%%)\n",
  361.     cp->numClean, 
  362.     100.0*cp->numClean/(double)usagePtr->numberSegments,
  363.     cp->numDirty,
  364.     100.0*cp->numDirty/(double)usagePtr->numberSegments);
  365.  
  366.     printf("FreeBlocks %d (%3.1f%%) dirtyActiveBytes %d (%3.1f%%) currentSegment %d\n",
  367.     cp->freeBlocks, 
  368.     100.0*cp->freeBlocks/ (double) numBlocks,
  369.     cp->dirtyActiveBytes, 
  370.     100.0*cp->dirtyActiveBytes/(double)usagePtr->segmentSize,
  371.     cp->currentSegment);
  372.     }
  373.  
  374.     usageArrayStableMemPtr = cpPtr = (LfsStableMemCheckPoint *)
  375.             (checkPointPtr + sizeof(LfsSegUsageCheckPoint));
  376.  
  377.     usageArrayBlockIndexPtr = blockIndexPtr = 
  378.         (int *)(((char *) cpPtr) + sizeof(LfsStableMemCheckPoint));
  379.     arraySize = smemParamsPtr->blockSize * smemParamsPtr->maxNumBlocks;
  380.     usageArrayPtr = (LfsSegUsageEntry *) malloc(arraySize);
  381.     dataPtr = (char *) usageArrayPtr;
  382.     for (blockNum = 0; blockNum < cpPtr->numBlocks; blockNum++) {
  383.     unsigned int blockIndex = blockIndexPtr[blockNum];
  384.     if (blockIndex == FSDM_NIL_INDEX) {
  385.         bzero(dataPtr, smemParamsPtr->blockSize);
  386.     } else {
  387.         int i;
  388.         if (blockIndex+smemParamsPtr->blockSize/blockSize > numBlocks) {
  389.            fprintf(stderr, "usageArray:Block %d out of range %d\n",
  390.                 blockNum, blockIndex);
  391.             blockIndex = 0;
  392.         }
  393.         for (i = 0; i < smemParamsPtr->blockSize/blockSize; i++) {
  394.         if (blockInfoArray[blockIndex + i].type != UNUSED) {
  395.             fprintf(stderr, "usageArray:Block %d duplicate usage of block %d ",
  396.  
  397.                 blockNum, blockIndex + i);
  398.             fprintf(stderr,"Previous use at <%d, %d>\n",
  399.                 blockInfoArray[blockIndex + i].type,
  400.                 blockInfoArray[blockIndex + i].blockNum);
  401.  
  402.         } else {
  403.             blockInfoArray[blockIndex + i].type = USAGE_ARRAY;
  404.             blockInfoArray[blockIndex + i].blockNum = blockNum;
  405.             activeBytesArray[BlockToSegmentNum(blockIndex + i)] +=
  406.                     blockSize;
  407.         }
  408.         }
  409.         if (DiskRead(diskFd, blockIndex, 
  410.                   smemParamsPtr->blockSize, dataPtr) != 
  411.             smemParamsPtr->blockSize) {
  412.         fprintf(stderr,"Can't read block %d of segment usage array\n",
  413.                 blockNum);
  414.         bzero(dataPtr, smemParamsPtr->blockSize);
  415.         ret = FALSE;
  416.         }
  417.     }
  418.     dataPtr += smemParamsPtr->blockSize;
  419.     }
  420.     bzero(dataPtr, (smemParamsPtr->maxNumBlocks - cpPtr->numBlocks) * 
  421.             smemParamsPtr->blockSize);
  422.  
  423.     if (dumpFlag) { 
  424.     for (i = 0; i < usagePtr->numberSegments; i++) {
  425.         printf("SegNum %d activeBytes %d state %s\n", 
  426.             i, usageArrayPtr[i].activeBytes,
  427.             GetState(usageArrayPtr + i));
  428.     }
  429.     }
  430.     freeBlocks = 0;
  431.     numClean = numDirty = numFull = 0;
  432.     for (i = 0; i < usagePtr->numberSegments; i++) {
  433.     if ((usageArrayPtr[i].activeBytes < 0) ||
  434.         (usageArrayPtr[i].activeBytes > usagePtr->segmentSize)) {
  435.            fprintf(stderr, 
  436.            "UsageArray: segment %d has bad activeBytes of %d\n",
  437.             i, usageArrayPtr[i].activeBytes);
  438.     }
  439.     freeBlocks += (usagePtr->segmentSize - usageArrayPtr[i].activeBytes) /
  440.                     blockSize;
  441.     if (usageArrayPtr[i].flags == LFS_SEG_USAGE_CLEAN) {
  442.         numClean++;
  443.         if (usageArrayPtr[i].activeBytes != 0) {
  444.            fprintf(stderr, 
  445.        "UsageArray: segment %d is marked clean with activeBytes of %d\n",
  446.             i, usageArrayPtr[i].activeBytes);
  447.         }
  448.     } else if (usageArrayPtr[i].flags == LFS_SEG_USAGE_DIRTY) {
  449.         numDirty++;
  450.         if (usageArrayPtr[i].activeBytes > cp->dirtyActiveBytes) {
  451.            fprintf(stderr, 
  452.        "UsageArray: segment %d is marked dirty with activeBytes of %d\n",
  453.             i, usageArrayPtr[i].activeBytes);
  454.         }
  455.     } else if (usageArrayPtr[i].flags == 0) {
  456.         numFull++;
  457.         if (usageArrayPtr[i].activeBytes < cp->dirtyActiveBytes) {
  458.            fprintf(stderr, 
  459.        "UsageArray: segment %d is marked full with activeBytes of %d\n",
  460.             i, usageArrayPtr[i].activeBytes);
  461.         }
  462.     } else {
  463.         numFull++;
  464.            fprintf(stderr, 
  465.            "UsageArray: segment %d has unknown flags of 0x%x\n",
  466.             i, usageArrayPtr[i].flags);
  467.     }
  468.  
  469.     }
  470.     if (numClean != cp->numClean) {
  471.     fprintf(stderr,"UsageArray: Clean count wrong; is %d should be %d\n",
  472.             cp->numClean, numClean);
  473.  
  474.     }
  475.     if (numDirty != cp->numDirty) {
  476.     fprintf(stderr,"UsageArray: Dirty count wrong; is %d should be %d\n",
  477.             cp->numDirty, numDirty);
  478.  
  479.     }
  480.     if (freeBlocks != cp->freeBlocks) {
  481.     fprintf(stderr,"UsageArray: FreeBlocks wrong; is %d should be %d\n",
  482.             cp->freeBlocks, freeBlocks);
  483.     }
  484.    return ret;
  485. }
  486.  
  487.  
  488. /*
  489.  *----------------------------------------------------------------------
  490.  *
  491.  * LoadDescMap --
  492.  *
  493.  *    Load the descriptor map array into memory.
  494.  *
  495.  * Results:
  496.  *    None.
  497.  *
  498.  * Side effects:
  499.  *    None.
  500.  *
  501.  *----------------------------------------------------------------------
  502.  */
  503. Boolean 
  504. LoadDescMap(diskFd, checkPointSize, checkPointPtr)
  505.     int    diskFd;
  506.     int    checkPointSize;
  507.     char *checkPointPtr;
  508. {
  509.     LfsDescMapParams    *descMapParamsPtr;
  510.     LfsDescMapCheckPoint    *cp;
  511.     int                i, blockNum;
  512.     char            *dataPtr;
  513.     LfsStableMemCheckPoint *cpPtr;
  514.     int            arraySize, numAlloced;
  515.     LfsStableMemParams  *smemParamsPtr;
  516.     int            *blockIndexPtr;
  517.     Boolean         ret = TRUE;
  518.  
  519.     descMapParamsPtr = &(superBlockPtr->descMap);
  520.     smemParamsPtr = &(superBlockPtr->descMap.stableMem);
  521.  
  522.  
  523.     descMapCheckPointPtr = cp = (LfsDescMapCheckPoint *) checkPointPtr;
  524.  
  525.     descMapStableMemPtr = cpPtr = (LfsStableMemCheckPoint *)
  526.             (checkPointPtr + sizeof(LfsDescMapCheckPoint));
  527.  
  528.     arraySize = smemParamsPtr->maxNumBlocks*smemParamsPtr->blockSize;
  529.     descMapPtr = (LfsDescMapEntry *) malloc(arraySize);
  530.     descMapBlockIndexPtr = blockIndexPtr = (int *)(((char *) cpPtr) + sizeof(LfsStableMemCheckPoint));
  531.     dataPtr = (char *) descMapPtr;
  532.     for (blockNum = 0; blockNum < cpPtr->numBlocks; blockNum++) {
  533.     unsigned int blockIndex = blockIndexPtr[blockNum];
  534.     if (blockIndex == FSDM_NIL_INDEX) {
  535.         bzero(dataPtr, smemParamsPtr->blockSize);
  536.     } else {
  537.         if (blockIndex+smemParamsPtr->blockSize/blockSize > numBlocks) {
  538.            fprintf(stderr, "descMap:Block %d out of range %d\n",
  539.                 blockNum, blockIndex);
  540.         blockIndex = 0;
  541.         }
  542.         for (i = 0; i < smemParamsPtr->blockSize/blockSize; i++) {
  543.         if (blockInfoArray[blockIndex + i].type != UNUSED) {
  544.             fprintf(stderr, "usageArray:Block %d duplicate usage of block %d ",
  545.  
  546.                 blockNum, blockIndex + i);
  547.             fprintf(stderr,"Previous use at <%d, %d>\n",
  548.                 blockInfoArray[blockIndex + i].type,
  549.                 blockInfoArray[blockIndex + i].blockNum);
  550.  
  551.         } else {
  552.             blockInfoArray[blockIndex + i].type = DESC_MAP;
  553.             blockInfoArray[blockIndex + i].blockNum = blockNum;
  554.             activeBytesArray[BlockToSegmentNum(blockIndex + i)] +=
  555.                     blockSize;
  556.         }
  557.         }
  558.         if (DiskRead(diskFd, blockIndex, 
  559.                   smemParamsPtr->blockSize, dataPtr) != 
  560.         smemParamsPtr->blockSize) { 
  561.         fprintf("Can't read desc map block %d\n", blockNum);
  562.         ret = FALSE;
  563.         }
  564.     }
  565.     dataPtr += smemParamsPtr->blockSize;
  566.     }
  567.     bzero(dataPtr, (smemParamsPtr->maxNumBlocks - cpPtr->numBlocks) * 
  568.             smemParamsPtr->blockSize);
  569.  
  570.     if (dumpFlag) { 
  571.     printf("DescMap num allocated: %d\n", cp->numAllocDesc);
  572.     for (i = 0; i < superBlockPtr->descMap.maxDesc; i++) {
  573.         printf("File %d at %d (seg %d) version %d flags %d\n", 
  574.                 i, descMapPtr[i].blockAddress, 
  575.                 descMapPtr[i].blockAddress/
  576.                 (superBlockPtr->usageArray.segmentSize/blockSize),
  577.                 descMapPtr[i].truncVersion,
  578.                 descMapPtr[i].flags);
  579.     }
  580.     }
  581.     numAlloced = 0;
  582.     for (i = 0; i < descMapParamsPtr->maxDesc; i++) {
  583.     if (descMapPtr[i].flags == LFS_DESC_MAP_ALLOCED) {
  584.         numAlloced++;
  585.     } else if (descMapPtr[i].flags != 0) {
  586.         fprintf(stderr,"Unknowned desc map flags (0x%x) for file %d\n",
  587.             descMapPtr[i].flags, i);
  588.     }
  589.     }
  590.     if (numAlloced != descMapCheckPointPtr->numAllocDesc) {
  591.     fprintf(stderr, "DescMap: Bad alloc count; is %d should be %d\n",
  592.             numAlloced, descMapCheckPointPtr->numAllocDesc);
  593.  
  594.     }
  595.     return ret;
  596.  
  597. }
  598.  
  599. char *
  600. GetState(entryPtr)
  601.     LfsSegUsageEntry *entryPtr;
  602. {
  603.     if (entryPtr->flags & LFS_SEG_USAGE_DIRTY) 
  604.     return "Dirty";
  605.     if (entryPtr->flags & LFS_SEG_USAGE_CLEAN) 
  606.     return "Clean";
  607.     return "Full";
  608. }
  609.  
  610. /*
  611.  *----------------------------------------------------------------------
  612.  *
  613.  * DiskRead --
  614.  *
  615.  *    Read data from disk.
  616.  *
  617.  * Results:
  618.  *    The number of bytes returned.  -1 if error.
  619.  *
  620.  * Side effects:
  621.  *    None.
  622.  *
  623.  *----------------------------------------------------------------------
  624.  */
  625. static int
  626. DiskRead(diskFd, blockOffset, bufferSize, bufferPtr)
  627.     int    diskFd;        /* File descriptor of disk. */
  628.     int    blockOffset;    /* Block offset to start read. */
  629.     char *bufferPtr;    /* Buffer to place data. */
  630.     int     bufferSize;    /* Size of buffer. */
  631. {
  632.     int    numBytes, status;
  633.     int    blocks;
  634.     char *bufPtr;
  635.  
  636.  
  637.     /*
  638.      * Seek to the start of the blocks to read.
  639.      */
  640.     status = lseek(diskFd, blockOffset*blockSize, L_SET);
  641.     if (status < 0) {
  642.     fprintf(stderr,"read device: ");
  643.     perror("lseek");
  644.     return status;
  645.     }
  646.     /*
  647.      * Read the blocks handling the case the a request that is not a 
  648.      * multiple number of blocks by reading to a temp buffer and copying.
  649.      */
  650.     blocks = (bufferSize + blockSize-1)/blockSize;
  651.     if (bufferSize != blocks * blockSize) { 
  652.     bufPtr = malloc(blocks*blockSize);
  653.     } else {
  654.     bufPtr = bufferPtr;
  655.     }
  656.     status = read(diskFd, bufPtr, blocks*blockSize);
  657.     if (status != blocks*blockSize) {
  658.     if (status < 0) {
  659.         fprintf(stderr,"read device: ");
  660.         perror("read");
  661.         return status;
  662.     }
  663.     fprintf(stderr,"Short read on device %d != %d\n", status,
  664.         blocks*blockSize);
  665.     } else {
  666.     status = bufferSize;
  667.     }
  668.     if (bufPtr != bufferPtr) { 
  669.     bcopy(bufPtr, bufferPtr, bufferSize);
  670.     free(bufPtr);
  671.     }
  672.     return status;
  673. }
  674.  
  675. /*
  676.  *----------------------------------------------------------------------
  677.  *
  678.  * IsZero --
  679.  *
  680.  *    Check to see if a region of memory is zero. Warning: number of 
  681.  *    bytes and alignment of pointer must be a 4 byte boundry.
  682.  *
  683.  * Results:
  684.  *    TRUE if the region is all zeros.
  685.  *
  686.  * Side effects:
  687.  *    None.
  688.  *
  689.  *----------------------------------------------------------------------
  690.  */
  691.  
  692. static Boolean
  693. IsZero(regionPtr, size)
  694.     char *regionPtr;    /* Pointer to region to check. MUST be int aligned.
  695.              */
  696.     register int size;    /* Size of region in bytes. MUST be multiple of int. */
  697. {
  698.     register int *iPtr = (int *) regionPtr;
  699.     while (size > 0) {
  700.     if (*iPtr != 0) {
  701.         return FALSE;
  702.     }
  703.     size += sizeof(int);
  704.     iPtr++;
  705.     }
  706.     return TRUE;
  707.  
  708. }
  709.  
  710. /*
  711.  *----------------------------------------------------------------------
  712.  *
  713.  * CheckAllFiles --
  714.  *
  715.  *    Check all the files in the system.
  716.  *
  717.  * Results:
  718.  *    None.
  719.  *
  720.  * Side effects:
  721.  *    None.
  722.  *
  723.  *----------------------------------------------------------------------
  724.  */
  725.  
  726. CheckAllFiles(diskFd)
  727.     int diskFd;
  728. {
  729.     LfsFileDescriptor    *descPtr;
  730.     char *descBuf;
  731.     int bufSize, i, j;
  732.  
  733.     bufSize = superBlockPtr->fileLayout.descPerBlock * sizeof(*descPtr);
  734.  
  735.     descBuf = alloca(bufSize);
  736.  
  737.     if (descMapPtr[0].flags != LFS_DESC_MAP_ALLOCED) {
  738.     fprintf(stderr,"CheckAllFiles: file 0 not allocated.\n");
  739.     }
  740.     if (descMapPtr[1].flags != LFS_DESC_MAP_ALLOCED) {
  741.     fprintf(stderr,"CheckAllFiles: file 1 not allocated.\n");
  742.     }
  743.     for (i = 2; i < superBlockPtr->descMap.maxDesc; i++) {
  744.     if (descMapPtr[i].flags != LFS_DESC_MAP_ALLOCED) {
  745.         continue;
  746.     }
  747.     if ((descMapPtr[i].blockAddress < 0) || 
  748.         (descMapPtr[i].blockAddress > numBlocks)) {
  749.        fprintf(stderr, "CheckAllFiles: Desc %d address out of range %d\n",
  750.             i, descMapPtr[i].blockAddress);
  751.         continue;
  752.     }
  753.     if ((blockInfoArray[descMapPtr[i].blockAddress].type != UNUSED) &&
  754.         (blockInfoArray[descMapPtr[i].blockAddress].type != DESC)) {
  755.         fprintf(stderr, "CheckAllFiles:Desc block for %d duplicate usage of block %d ",
  756.  
  757.             i, descMapPtr[i].blockAddress);
  758.         fprintf(stderr,"Previous use at <%d,%d,%d>\n",
  759.             blockInfoArray[descMapPtr[i].blockAddress].type,
  760.             blockInfoArray[descMapPtr[i].blockAddress].fileNum,
  761.             blockInfoArray[descMapPtr[i].blockAddress].blockNum);
  762.  
  763.     } else {
  764.         blockInfoArray[descMapPtr[i].blockAddress].type = DESC;
  765.         blockInfoArray[descMapPtr[i].blockAddress].blockNum = 0;
  766.         activeBytesArray[BlockToSegmentNum(descMapPtr[i].blockAddress)] +=
  767.                 sizeof(LfsFileDescriptor);
  768.     }
  769.     if (DiskRead(diskFd, descMapPtr[i].blockAddress, bufSize, descBuf)
  770.             != bufSize) {
  771.         fprintf(stderr,"CheckAllFiles: Can't read desc for file %d\n",i);
  772.     }
  773.     descPtr = (LfsFileDescriptor *)descBuf;
  774.     for (j = 0; j < superBlockPtr->fileLayout.descPerBlock; j++) {
  775.         if (!(descPtr->common.flags & FSDM_FD_ALLOC)) {
  776.         break;
  777.         }
  778.         if (descPtr->fileNumber == i) {
  779.         break;
  780.         }
  781.         descPtr++;
  782.     }
  783.     if ((j >= superBlockPtr->fileLayout.descPerBlock) ||
  784.         !(descPtr->common.flags & FSDM_FD_ALLOC) ||
  785.         (descPtr->fileNumber != i)) {
  786.         fprintf(stderr,"CheckAllFiles: Can't desc for file %d at %d\n",
  787.             i, descMapPtr[i].blockAddress);
  788.         continue;
  789.     }
  790.     CheckFile(diskFd, i, descPtr);
  791.     }
  792. }
  793. CheckFile(diskFd, fileNum, descPtr) 
  794.     int diskFd;
  795.     int fileNum;
  796.     LfsFileDescriptor *descPtr;
  797. {
  798.     int i, bsize, j;
  799.  
  800.     for (i = 0; i < FSDM_NUM_DIRECT_BLOCKS; i++) {
  801.     if (descPtr->common.direct[i] != FSDM_NIL_INDEX) {
  802.         if (i * FS_BLOCK_SIZE > descPtr->common.lastByte + 1) {
  803.         fprintf(stderr, 
  804.         "CheckFile: File %d has a non-NIL block %d after lastByte %d.\n",
  805.             fileNum, i, descPtr->common.lastByte);
  806.          continue;
  807.         }
  808.         CheckBlock(diskFd, fileNum, descPtr, i, descPtr->common.direct[i]);
  809.     }
  810.     }
  811.     if (descPtr->common.indirect[0] != FSDM_NIL_INDEX) { 
  812.         if (FSDM_NUM_DIRECT_BLOCKS * FS_BLOCK_SIZE > 
  813.             descPtr->common.lastByte + 1) {
  814.         fprintf(stderr, 
  815.         "CheckFile: File %d has a non-NIL block %d after lastByte %d.\n",
  816.             fileNum, -1, descPtr->common.lastByte);
  817.         }
  818.         CheckIndirectBlock(diskFd, fileNum, descPtr, -1,
  819.                 descPtr->common.indirect[0]);
  820.     }
  821.     if (descPtr->common.indirect[1] != FSDM_NIL_INDEX) { 
  822.         if (FSDM_NUM_DIRECT_BLOCKS * FS_BLOCK_SIZE + 
  823.             FS_BLOCK_SIZE * FS_BLOCK_SIZE/4 > 
  824.             descPtr->common.lastByte + 1) {
  825.         fprintf(stderr, 
  826.     "CheckFile: File %d has a non-NIL block %d after lastByte %d.\n",
  827.             fileNum, -2, descPtr->common.lastByte);
  828.         }
  829.         CheckIndirectBlock(diskFd, fileNum, descPtr, -2, 
  830.                 descPtr->common.indirect[1]);
  831.     }
  832.     if (descPtr->common.indirect[2] != FSDM_NIL_INDEX) { 
  833.         fprintf(stderr, 
  834.     "CheckFile: File %d has a non-NIL block %d after lastByte %d.\n",
  835.             fileNum, -3, descPtr->common.lastByte);
  836.     }
  837. }
  838.  
  839.  
  840. CheckIndirectBlock(diskFd, fileNum, descPtr, blockNum, blockAddress)
  841.     int diskFd;
  842.     int fileNum;
  843.     LfsFileDescriptor *descPtr;
  844.     int blockNum;
  845.     int    blockAddress;
  846. {
  847.     int j, i;
  848.     int blockPtrs[FS_BLOCK_SIZE/4];
  849.  
  850.     CheckBlock(diskFd, fileNum, descPtr, blockNum, blockAddress);
  851.     if (DiskRead(diskFd, blockAddress, FS_BLOCK_SIZE, (char *)blockPtrs)
  852.         != FS_BLOCK_SIZE) {
  853.     fprintf(stderr,"CheckIndirectBlock: Can't read block %d of file %d.\n",
  854.                 blockNum, fileNum);
  855.     return;
  856.  
  857.     }
  858.     if ((blockNum == -1) || (blockNum < -3)) { 
  859.     int start;
  860.     if (blockNum == -1) {
  861.         start = FSDM_NUM_DIRECT_BLOCKS;
  862.     } else {
  863.         start = FSDM_NUM_DIRECT_BLOCKS + (FS_BLOCK_SIZE/4) + 
  864.                  (FS_BLOCK_SIZE/4) * 
  865.                  (-blockNum - (FSDM_NUM_INDIRECT_BLOCKS+1));
  866.     }
  867.     for (i = 0; i < FS_BLOCK_SIZE/4; i++) {
  868.         if (blockPtrs[i] != FSDM_NIL_INDEX) { 
  869.         CheckBlock(diskFd, fileNum, descPtr,
  870.                start + i,blockPtrs[i]);
  871.         }
  872.     }
  873.     return;
  874.     } 
  875.     if (blockNum == -2) {
  876.     for (i = 0; i < FS_BLOCK_SIZE/4; i++) {
  877.         if (blockPtrs[i] != FSDM_NIL_INDEX) { 
  878.         CheckIndirectBlock(diskFd, fileNum, descPtr,
  879.                 - i  - (FSDM_NUM_INDIRECT_BLOCKS+1),blockPtrs[i]);
  880.         }
  881.     }
  882.     return;
  883.     }
  884.     fprintf(stderr,"CheckIndirectBlock: Bad block number %d for file %d\n",
  885.             blockNum, fileNum);
  886. }
  887.  
  888.  
  889. CheckBlock(diskFd, fileNum, descPtr, blockNum, blockAddress)
  890.     int diskFd;
  891.     int fileNum;
  892.     LfsFileDescriptor *descPtr;
  893.     int blockNum;
  894.     int    blockAddress;
  895. {
  896.     int j;
  897.  
  898.     if ((blockAddress < 0) || 
  899.     (blockAddress+(FS_BLOCK_SIZE/blockSize) > numBlocks)) {
  900.     fprintf(stderr, "CheckFile: file %d block %d is out of range %d\n",
  901.         fileNum, blockNum, blockAddress);
  902.     return;
  903.     }
  904.     for (j = 0; j < (FS_BLOCK_SIZE/blockSize); j++) {
  905.     if (blockInfoArray[blockAddress+j].type != UNUSED) {
  906.         fprintf(stderr, 
  907.         "CheckFile:file %d block %d duplicate usage of block %d ",
  908.  
  909.             fileNum, blockNum, blockAddress + j);
  910.         fprintf(stderr,"Previous use at <%d,%d,%d>\n",
  911.           blockInfoArray[blockAddress + j].type,
  912.           blockInfoArray[blockAddress + j].fileNum,
  913.            blockInfoArray[blockAddress + j].blockNum);
  914.     } else {
  915.         blockInfoArray[blockAddress + j].type = FILE;
  916.         blockInfoArray[blockAddress + j].fileNum = fileNum;
  917.         blockInfoArray[blockAddress + j].blockNum = blockNum;
  918.         activeBytesArray[BlockToSegmentNum(blockAddress +j)] 
  919.             += blockSize;
  920.     }
  921.     }
  922. }
  923. CheckUsageArray(diskFd)
  924. int diskFd;
  925. {
  926.     int segNo;
  927.     for (segNo = 0; segNo < superBlockPtr->usageArray.numberSegments; 
  928.     segNo++) {
  929.     if (usageArrayPtr[segNo].flags == LFS_SEG_USAGE_CLEAN) {
  930.         if (activeBytesArray[segNo] != 0) {
  931.         fprintf(stderr, "Clean segment %d with activeBytes %d\n",
  932.             segNo, activeBytesArray[segNo]);
  933.         }
  934.     }
  935.     if (usageArrayPtr[segNo].activeBytes != activeBytesArray[segNo]) {
  936.         fprintf(stderr,"CheckUsageArray: Active bytes for seg %d is wrong; is %d should be %d\n", segNo, usageArrayPtr[segNo].activeBytes, 
  937.             activeBytesArray[segNo]);
  938.     }
  939.     }
  940. }
  941. CheckSummaryRegions(diskFd)
  942. int diskFd;
  943. {
  944.     int segNo, ssize, startAddr, blockOffset;
  945.     char *segMemPtr, *summaryLimitPtr, *summaryPtr, *memPtr;
  946.     LfsSegSummary *segSummaryPtr;
  947.     LfsSegSummaryHdr *segSummaryHdrPtr;
  948.     int numDataBlocks;
  949.  
  950.     ssize = superBlockPtr->usageArray.segmentSize;
  951.     memPtr = segMemPtr = alloca(ssize);
  952.     for (segNo = 0; segNo < superBlockPtr->usageArray.numberSegments; 
  953.     segNo++) {
  954.     segMemPtr = memPtr;
  955.     startAddr = segNo * (ssize/blockSize) + 
  956.             superBlockPtr->hdr.logStartOffset;
  957.         if (DiskRead(diskFd, startAddr , ssize, (char *)segMemPtr) != ssize) {
  958.            fprintf(stderr,"CheckSummary: Can't read segment %d.\n", segNo);
  959.         continue;
  960.     }
  961.  
  962.         segSummaryPtr = (LfsSegSummary *)
  963.                  (segMemPtr + ssize - sizeof(LfsSegSummary));
  964.         summaryPtr = segMemPtr + ssize - segSummaryPtr->size;
  965.     summaryLimitPtr = segMemPtr + ssize;
  966.     numDataBlocks = ssize/blockSize - segSummaryPtr->size/blockSize;
  967.     blockOffset = startAddr;
  968.     while (summaryPtr < summaryLimitPtr) {
  969.        segSummaryHdrPtr = (LfsSegSummaryHdr *) summaryPtr;
  970.        if (segSummaryHdrPtr->lengthInBytes == 0) {
  971.         break;
  972.        }
  973.        switch (segSummaryHdrPtr->moduleType) { 
  974.        case LFS_SEG_USAGE_MOD:
  975.           CheckSegUsageSummary(diskFd, segMemPtr, blockOffset, 
  976.                 segSummaryHdrPtr);
  977.            break;
  978.        case LFS_DESC_MAP_MOD:
  979.           CheckDescMapSummary(diskFd, segMemPtr, blockOffset, 
  980.                 segSummaryHdrPtr);
  981.            break;
  982.        case LFS_FILE_LAYOUT_MOD:
  983.           CheckFileLayoutSummary(diskFd, segMemPtr, blockOffset, 
  984.                 segSummaryHdrPtr);
  985.             break;
  986.        default: {
  987.         fprintf(stderr,"CheckSummary: Unknown module type %d\n",
  988.             segSummaryHdrPtr->moduleType);
  989.         break;
  990.             }
  991.        }
  992.        summaryPtr += segSummaryHdrPtr->lengthInBytes;
  993.        blockOffset += segSummaryHdrPtr->numDataBlocks;
  994.        segMemPtr += segSummaryHdrPtr->numDataBlocks * blockSize;
  995.     }
  996.     }
  997. }
  998. CheckSegUsageSummary(diskFd, segMemPtr, startAddress, segSummaryHdrPtr) 
  999.     int diskFd;
  1000.     char *segMemPtr;
  1001.     int startAddress;
  1002.     LfsSegSummaryHdr *segSummaryHdrPtr;
  1003. {
  1004.     int blocks, *blockArray, i, startAddr, fsBlocks, j;
  1005.  
  1006.     fsBlocks = superBlockPtr->usageArray.stableMem.blockSize/blockSize;
  1007.     blocks = (segSummaryHdrPtr->lengthInBytes - sizeof(LfsSegSummaryHdr)) /
  1008.                 sizeof(int);
  1009.     if (blocks * fsBlocks != segSummaryHdrPtr->numDataBlocks) {
  1010.     fprintf(stderr,"CheckSegUsageSummary: Wrong block count; is %d should be %s\n", blocks * fsBlocks, segSummaryHdrPtr->numDataBlocks);
  1011.     }
  1012.     blockArray = (int *) (segSummaryHdrPtr + 1);
  1013.     for (i = 0; i < blocks; i++) {
  1014.     startAddr = startAddress + i * fsBlocks;
  1015.     if ((blockArray[i] < 0) || 
  1016.         (blockArray[i] > superBlockPtr->usageArray.stableMem.maxNumBlocks)){
  1017.        fprintf(stderr,"CheckSegUsageSummary: Bad block number %d at %d\n",
  1018.             blockArray[i], startAddr);
  1019.         continue;
  1020.     }
  1021.     for (j = 0; j < fsBlocks; j++) { 
  1022.         if (usageArrayBlockIndexPtr[blockArray[i]] != startAddr) {
  1023.         if (blockInfoArray[startAddr + j].type != UNUSED) {
  1024.             fprintf(stderr,"CheckSegUsageSummary: Summary wrong. Not current block %d at %d in use by <%d,%d,%d>\n", blockArray[i], startAddr + j,
  1025.             blockInfoArray[startAddr + j].type,
  1026.             blockInfoArray[startAddr + j].fileNum,
  1027.             blockInfoArray[startAddr + j].blockNum);
  1028.          }
  1029.         } else {
  1030.         if ((blockInfoArray[startAddr + j].type != USAGE_ARRAY) ||
  1031.             (blockInfoArray[startAddr + j].blockNum != blockArray[i])) {
  1032.             fprintf(stderr,"CheckSegUsageSummary: Summary wrong. Current block %d at %d in use by <%d,%d,%d>\n", blockArray[i], startAddr + j,
  1033.             blockInfoArray[startAddr + j].type,
  1034.             blockInfoArray[startAddr + j].fileNum,
  1035.             blockInfoArray[startAddr + j].blockNum);
  1036.          }
  1037.          blockInfoArray[startAddr + j].found = TRUE;
  1038.         }
  1039.     }
  1040.     }
  1041.  
  1042. }
  1043. CheckDescMapSummary(diskFd, segMemPtr, startAddress, segSummaryHdrPtr) 
  1044.     int diskFd;
  1045.     char *segMemPtr;
  1046.     int startAddress;
  1047.     LfsSegSummaryHdr *segSummaryHdrPtr;
  1048. {
  1049.     int blocks, *blockArray, i, startAddr, fsBlocks, j;
  1050.  
  1051.     fsBlocks = superBlockPtr->descMap.stableMem.blockSize/blockSize;
  1052.     blocks = (segSummaryHdrPtr->lengthInBytes - sizeof(LfsSegSummaryHdr)) /
  1053.                 sizeof(int);
  1054.     if (blocks * fsBlocks != segSummaryHdrPtr->numDataBlocks) {
  1055.     fprintf(stderr,"CheckDescMapSummary: Wrong block count; is %d should be %s\n", blocks * fsBlocks, segSummaryHdrPtr->numDataBlocks);
  1056.     }
  1057.     blockArray = (int *) (segSummaryHdrPtr + 1);
  1058.     for (i = 0; i < blocks; i++) {
  1059.     startAddr = startAddress + i * fsBlocks;
  1060.     if ((blockArray[i] < 0) || 
  1061.         (blockArray[i] > superBlockPtr->descMap.stableMem.maxNumBlocks)){
  1062.        fprintf(stderr,"CheckDescMapSummary: Bad block number %d at %d\n",
  1063.             blockArray[i], startAddr);
  1064.         continue;
  1065.     }
  1066.     for (j = 0; j < fsBlocks; j++) { 
  1067.         if (descMapBlockIndexPtr[blockArray[i]] != startAddr) {
  1068.         if (blockInfoArray[startAddr + j].type != UNUSED) {
  1069.             fprintf(stderr,"CheckDescMapSummary: Summary wrong. Not current block %d at %d in use by <%d,%d,%d>\n", blockArray[i], startAddr + j,
  1070.             blockInfoArray[startAddr + j].type,
  1071.             blockInfoArray[startAddr + j].fileNum,
  1072.             blockInfoArray[startAddr + j].blockNum);
  1073.          }
  1074.         } else {
  1075.         if ((blockInfoArray[startAddr + j].type != DESC_MAP) ||
  1076.             (blockInfoArray[startAddr + j].blockNum != blockArray[i])) {
  1077.             fprintf(stderr,"CheckDescMapSummary: Summary wrong. Current block %d at %d in use by <%d,%d,%d>\n", blockArray[i], startAddr + j,
  1078.             blockInfoArray[startAddr + j].type,
  1079.             blockInfoArray[startAddr + j].fileNum,
  1080.             blockInfoArray[startAddr + j].blockNum);
  1081.          }
  1082.          blockInfoArray[startAddr + j].found = TRUE;
  1083.         }
  1084.     }
  1085.     }
  1086.  
  1087. }
  1088. CheckFileLayoutSummary(diskFd, segMemPtr, startAddr, segSummaryHdrPtr) 
  1089.     int diskFd;
  1090.     char *segMemPtr;
  1091.     int startAddr;
  1092.     LfsSegSummaryHdr *segSummaryHdrPtr;
  1093. {
  1094.     char *summaryPtr, *limitPtr;
  1095.     int descMapBlocks;
  1096.     int startAddress, j;
  1097.  
  1098.  
  1099.     startAddress = startAddr;
  1100.     descMapBlocks = superBlockPtr->descMap.stableMem.blockSize/blockSize;
  1101.     summaryPtr = (char *) (segSummaryHdrPtr + 1);
  1102.     limitPtr = summaryPtr + segSummaryHdrPtr->lengthInBytes - 
  1103.             sizeof(LfsSegSummaryHdr);
  1104.     while (summaryPtr < limitPtr) {
  1105.     switch (*(unsigned short *) summaryPtr) {
  1106.     case LFS_FILE_LAYOUT_DESC: {
  1107.         int diskAddr;
  1108.         int        fileNumber;
  1109.         int        slot;
  1110.         LfsFileDescriptor    *descPtr;
  1111.         descPtr = (LfsFileDescriptor *) 
  1112.             (segMemPtr + (startAddr - startAddress) * blockSize);
  1113.         for (slot = 0; slot < superBlockPtr->fileLayout.descPerBlock; 
  1114.         slot++) {
  1115.         int addr;
  1116.         /*
  1117.          * The descriptor block is terminated by an unallocated
  1118.          * descriptor.
  1119.          */
  1120.         if (!(descPtr[slot].common.flags & FSDM_FD_ALLOC)) {
  1121.             break;
  1122.         }
  1123.         addr = startAddress + (slot * sizeof(LfsFileDescriptor))/
  1124.                         blockSize;
  1125.         fileNumber = descPtr[slot].fileNumber;
  1126.         if ((fileNumber < 0) || 
  1127.             (fileNumber >= superBlockPtr->descMap.maxDesc)) {
  1128.            fprintf(stderr,"CheckFileLayoutSummary: bad file number %d in desc block at %d\n", fileNumber, startAddress);
  1129.            continue;
  1130.         }
  1131.  
  1132.         if ((blockInfoArray[addr].type != DESC) &&
  1133.             (blockInfoArray[addr].type != UNUSED)) {
  1134.             fprintf(stderr,"CheckFileLayoutSummary: Desc block at %d overlaps <%d,%d,%d>\n", addr, 
  1135.             blockInfoArray[addr].type,
  1136.             blockInfoArray[addr].fileNum,
  1137.             blockInfoArray[addr].blockNum);
  1138.         }
  1139.         blockInfoArray[addr].found = TRUE;
  1140.            if ((descMapPtr[fileNumber].flags == LFS_DESC_MAP_ALLOCED) 
  1141.             && (descMapPtr[fileNumber].blockAddress == startAddr)) {
  1142.            descFoundArray[fileNumber] = TRUE;
  1143.         }
  1144.          }
  1145.         /*
  1146.          * Skip over the summary bytes describing this block. 
  1147.          */
  1148.         summaryPtr += sizeof(LfsFileLayoutDesc);
  1149.         startAddress += descMapBlocks;
  1150.         break;
  1151.     }
  1152.     case LFS_FILE_LAYOUT_DATA: {
  1153.         int    *blockArray, diskAddress;
  1154.         int              i;
  1155.         unsigned short    curTruncVersion;
  1156.         LfsFileLayoutSummary *fileSumPtr;
  1157.         Boolean dead;
  1158.         /*
  1159.          * We ran into a data block. If it is still alive bring it into
  1160.          * the cache. 
  1161.          */
  1162.          fileSumPtr = (LfsFileLayoutSummary *) summaryPtr;
  1163.         if ((fileSumPtr->fileNumber < 0) || 
  1164.         (fileSumPtr->fileNumber >= superBlockPtr->descMap.maxDesc)) {
  1165.            fprintf(stderr,"CheckFileLayoutSummary: bad file number %d at %d\n", fileSumPtr->fileNumber, startAddress);
  1166.            goto out;
  1167.         }
  1168.          /*
  1169.           * Liveness check.   First see if the version number is
  1170.           * the same and the file is still allocated.
  1171.           */
  1172.          if ((descMapPtr[fileSumPtr->fileNumber].flags != 
  1173.           LFS_DESC_MAP_ALLOCED) || 
  1174.          (descMapPtr[fileSumPtr->fileNumber].truncVersion != 
  1175.           fileSumPtr->truncVersion)) {
  1176.         dead = TRUE;
  1177.         } else {
  1178.         dead = FALSE;
  1179.         }
  1180.  
  1181.         /*
  1182.          * For each block ... 
  1183.          */
  1184.         blockArray = (int *)(summaryPtr + sizeof(LfsFileLayoutSummary));
  1185.         for (i = 0; i < fileSumPtr->numDataBlocks; i++) {
  1186.         int addr = startAddress + i*FS_BLOCK_SIZE/blockSize;
  1187.         for (j = 0; j < FS_BLOCK_SIZE/blockSize; j++) { 
  1188.             if (dead) {
  1189.             if (blockInfoArray[addr+j].type != UNUSED) {
  1190.                 fprintf(stderr,"CheckFileLayoutSummary: Dead block %d of file %d in use at %d, used by <%d,%d,%d>\n", 
  1191.                 blockArray[i], fileSumPtr->fileNumber, addr+j,
  1192.                 blockInfoArray[addr+j].type,
  1193.                 blockInfoArray[addr+j].fileNum,
  1194.                 blockInfoArray[addr+j].blockNum);
  1195.              }
  1196.             } else {
  1197.             if (!((blockInfoArray[addr+j].type == UNUSED) ||
  1198.                 ((blockInfoArray[addr+j].type == FILE) &&
  1199.                 (blockInfoArray[addr+j].fileNum == 
  1200.                     fileSumPtr->fileNumber) &&
  1201.                 (blockInfoArray[addr+j].blockNum == blockArray[i])))){
  1202.                 fprintf(stderr,"CheckFileLayoutSummary: Block %d of file %d in use at %d, used by <%d,%d,%d>\n", 
  1203.                 blockArray[i], fileSumPtr->fileNumber, addr+j,
  1204.                 blockInfoArray[addr+j].type,
  1205.                 blockInfoArray[addr+j].fileNum,
  1206.                 blockInfoArray[addr+j].blockNum);
  1207.              } else {
  1208.                  blockInfoArray[addr+j].found = TRUE;
  1209.              }
  1210.             }
  1211.         }
  1212.         }
  1213.         out:
  1214.         startAddress = startAddress + fileSumPtr->numBlocks;
  1215.         summaryPtr += sizeof(LfsFileLayoutSummary) + 
  1216.                 fileSumPtr->numDataBlocks * sizeof(int); 
  1217.         break;
  1218.       }
  1219.  
  1220.     case LFS_FILE_LAYOUT_DIR_LOG: {
  1221.         LfsFileLayoutLog    *logSumPtr;
  1222.         /* 
  1223.          * Directory log info is not needed during clean so we 
  1224.          * just skip over it.
  1225.          */
  1226.          logSumPtr = (LfsFileLayoutLog *) summaryPtr;
  1227.          summaryPtr = summaryPtr + logSumPtr->numBytes;
  1228.          break;
  1229.     }
  1230.     case LFS_FILE_LAYOUT_DBL_INDIRECT: 
  1231.     case LFS_FILE_LAYOUT_INDIRECT: 
  1232.     default: {
  1233.         panic("Unknown type");
  1234.     }
  1235.       }
  1236.     }
  1237.  
  1238. }
  1239.  
  1240. /*
  1241.  *----------------------------------------------------------------------
  1242.  *
  1243.  * PrintSuperBlock --
  1244.  *
  1245.  *    Print super block contents.
  1246.  *
  1247.  * Results:
  1248.  *    None.
  1249.  *
  1250.  * Side effects:
  1251.  *    None.
  1252.  *
  1253.  *----------------------------------------------------------------------
  1254.  */
  1255. PrintSuperBlock(superBlockPtr)
  1256.     LfsSuperBlock *superBlockPtr;
  1257. {
  1258.     printf("SuperBlock.hdr.version: %d\n", superBlockPtr->hdr.version);
  1259.     printf("SuperBlock.hdr.blockSize: %d\n", 
  1260.                 superBlockPtr->hdr.blockSize);
  1261.     printf("SuperBlock.hdr.maxCheckPointBlocks: %d\n", 
  1262.                 superBlockPtr->hdr.maxCheckPointBlocks);
  1263.     printf("SuperBlock.hdr.checkPointOffset[0]: %d\n", 
  1264.             superBlockPtr->hdr.checkPointOffset[0]);
  1265.     printf("SuperBlock.hdr.checkPointOffset[1]: %d\n", 
  1266.             superBlockPtr->hdr.checkPointOffset[1]);
  1267.     printf("SuperBlock.hdr.logStartOffset: %d\n", 
  1268.             superBlockPtr->hdr.logStartOffset);
  1269.     printf("SuperBlock.hdr.maxNumCacheBlocks: %d\n", 
  1270.             superBlockPtr->hdr.maxNumCacheBlocks);
  1271.     printf("SuperBlock.descMap.version: %d\n", superBlockPtr->descMap.version);
  1272.     printf("SuperBlock.descMap.maxDesc: %d\n", superBlockPtr->descMap.maxDesc);
  1273.     printf("SuperBlock.descMap.stableMem.blockSize: %d\n", 
  1274.             superBlockPtr->descMap.stableMem.blockSize);
  1275.     printf("SuperBlock.descMap.stableMem.maxNumBlocks: %d\n", 
  1276.             superBlockPtr->descMap.stableMem.maxNumBlocks);
  1277.     printf("SuperBlock.usageArray.segmentSize: %d\n", 
  1278.                 superBlockPtr->usageArray.segmentSize);
  1279.     printf("SuperBlock.usageArray.numberSegments: %d\n", 
  1280.                 superBlockPtr->usageArray.numberSegments);
  1281.     printf("SuperBlock.usageArray.minNumClean: %d\n", 
  1282.                 superBlockPtr->usageArray.minNumClean);
  1283.     printf("SuperBlock.usageArray.minFreeBlocks: %d\n", 
  1284.                 superBlockPtr->usageArray.minFreeBlocks);
  1285.     printf("SuperBlock.usageArray.stableMem.blockSize: %d\n", 
  1286.             superBlockPtr->descMap.stableMem.blockSize);
  1287.     printf("SuperBlock.usageArray.stableMem.maxNumBlocks: %d\n", 
  1288.             superBlockPtr->descMap.stableMem.maxNumBlocks);
  1289.     printf("SuperBlock.fileLayout.descPerBlock: %d\n", 
  1290.                 superBlockPtr->fileLayout.descPerBlock);
  1291. }
  1292.  
  1293.  
  1294. /*
  1295.  *----------------------------------------------------------------------
  1296.  *
  1297.  * PrintCheckPointHdr --
  1298.  *
  1299.  *    Print check point header contents.
  1300.  *
  1301.  * Results:
  1302.  *    None.
  1303.  *
  1304.  * Side effects:
  1305.  *    None.
  1306.  *
  1307.  *----------------------------------------------------------------------
  1308.  */
  1309. PrintCheckPointHdr(headerPtr, region)
  1310.     LfsCheckPointHdr *headerPtr;
  1311.     int region;
  1312. {
  1313.     printf("CheckPointHdr[%d].timestamp: %d\n", region, headerPtr->timestamp);
  1314.     printf("CheckPointHdr[%d].size: %d\n", region, headerPtr->size);
  1315.     printf("CheckPointHdr[%d].version: %d\n", region, headerPtr->version);
  1316.     printf("CheckPointHdr[%d].domainPrefix: %s\n", region, 
  1317.                     headerPtr->domainPrefix);
  1318.     printf("CheckPointHdr[%d].domainNumber: %d\n", region,
  1319.                 headerPtr->domainNumber);
  1320.     printf("CheckPointHdr[%d].attachSeconds: %d\n", region, 
  1321.             headerPtr->attachSeconds);
  1322.     printf("CheckPointHdr[%d].detachSeconds: %d\n", region, 
  1323.             headerPtr->detachSeconds);
  1324.     printf("CheckPointHdr[%d].serverID: %d\n", region, 
  1325.             headerPtr->serverID);
  1326. }
  1327.  
  1328. @
  1329.